package com.atguigu.gmall.item.service.impl;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.common.exception.ItemException;
import com.atguigu.gmall.item.feign.GmallPmsClient;
import com.atguigu.gmall.item.feign.GmallSmsClient;
import com.atguigu.gmall.item.feign.GmallWmsClient;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.item.vo.ItemVo;
import com.atguigu.gmall.pms.api.GmallPmsApi;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.vo.ItemGroupVo;
import com.atguigu.gmall.pms.vo.SaleAttrValueVo;
import com.atguigu.gmall.sms.api.GmallSmsApi;
import com.atguigu.gmall.sms.vo.ItemSaleVo;
import com.atguigu.gmall.wms.api.GmallWmsApi;
import com.atguigu.gmall.wms.entity.WareSkuEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    GmallPmsClient gmallPmsApi;
    @Autowired
    GmallSmsClient gmallSmsApi;
    @Autowired
    GmallWmsClient gmallWmsApi;
    @Autowired
    ThreadPoolExecutor executor;

    @Autowired
    TemplateEngine templateEngine;

    @Override
    public ItemVo skuItem(Long skuId) {
        ItemVo itemVo = new ItemVo();
        //1.根据skuId查询sku  V
        CompletableFuture<SkuEntity> skuFuture = CompletableFuture.supplyAsync(() -> {
            ResponseVo<SkuEntity> skuEntityResponseVo = gmallPmsApi.querySkuById(skuId);
            SkuEntity skuEntity = skuEntityResponseVo.getData();
            if (skuEntity == null) {
                throw new ItemException("访问商品不存在");
            }
            itemVo.setSkuId(skuId);
            itemVo.setPrice(skuEntity.getPrice());
            itemVo.setDefaultImage(skuEntity.getDefaultImage());
            itemVo.setSubTitle(skuEntity.getTitle());
            itemVo.setTitle(skuEntity.getTitle());
            itemVo.setWeight(skuEntity.getWeight());
            return skuEntity;
        }, executor);
        //2.根据三级分类的id查询一二三级分类 V
        CompletableFuture<Void> cateFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<CategoryEntity>> listResponseVo = gmallPmsApi.queryCategory12ByCid(skuEntity.getCategoryId());
            List<CategoryEntity> categoryEntities = listResponseVo.getData();
            itemVo.setCategories(categoryEntities);
        }, executor);
        //3.根据品牌id查询品牌  V
        CompletableFuture<Void> brandFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<BrandEntity> brandEntityResponseVo = gmallPmsApi.queryBrandById(skuEntity.getBrandId());
            BrandEntity brandEntity = brandEntityResponseVo.getData();
            itemVo.setBrandName(brandEntity.getName());
            itemVo.setBrandId(skuEntity.getBrandId());
        }, executor);
        //4.根据spuId查询spu  V
        CompletableFuture<Void> spuFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<SpuEntity> spuEntityResponseVo = gmallPmsApi.querySpuById(skuEntity.getSpuId());
            SpuEntity spuEntity = spuEntityResponseVo.getData();
            itemVo.setSpuId(spuEntity.getId());
            itemVo.setSpuName(spuEntity.getName());
        }, executor);
        //5.根据skuId查询sku的图片列表  V
        CompletableFuture<Void> skuDescFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<SkuImagesEntity>> skuImagesById = gmallPmsApi.querySkuImagesBySkuId(skuId);
            List<SkuImagesEntity> skuImagesEntities = skuImagesById.getData();
            itemVo.setImages(skuImagesEntities);
        }, executor);
        //6.根据skuId查询sku的营销信息 V sms 服务
        CompletableFuture<Void> saleFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<ItemSaleVo>> listResponseVo1 = gmallSmsApi.queryItemSaleBySkuId(skuId);
            List<ItemSaleVo> itemSaleVos = listResponseVo1.getData();
            if (!CollectionUtils.isEmpty(itemSaleVos)) {
                itemVo.setSales(itemSaleVos);
            }
        }, executor);
        //7.根据skuId查询库存列表  V wms服务
        CompletableFuture<Void> wareFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<WareSkuEntity>> wareSkusBySkuId = gmallWmsApi.queryWareSkusBySkuId(skuId);
            List<WareSkuEntity> wareSkuEntities = wareSkusBySkuId.getData();
            wareSkuEntities.forEach(wareSkuEntity -> {
                if (wareSkuEntity.getStock() > 0) {
                    itemVo.setStore(true);
                }
            });
        }, executor);
        //8.根据spuId查询spu下所有sku的销售属性 V {attrId: 5, attrName: 存储, attrValues: ['128G', '256G']}]
        //
        CompletableFuture<Void> saleAttrFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<SaleAttrValueVo>> skuSaleAtrrBySpuId = gmallPmsApi.querySkuSaleAtrrBySpuId(skuEntity.getSpuId());
            List<SaleAttrValueVo> saleAttrValueVos = skuSaleAtrrBySpuId.getData();
            itemVo.setSaleAttrs(saleAttrValueVos);
        }, executor);
        //9.根据skuId查询当前sku的销售属性 V
        CompletableFuture<Void> skuAttrFuture = CompletableFuture.runAsync(() -> {
            ResponseVo<List<SkuAttrValueEntity>> saleAttrValuesBySkuId = gmallPmsApi.querySaleAttrValuesBySkuId(skuId);
            List<SkuAttrValueEntity> skuAttrValueEntities = saleAttrValuesBySkuId.getData();
            itemVo.setSaleAttr(skuAttrValueEntities.stream().collect(Collectors.toMap(SkuAttrValueEntity::getAttrId, SkuAttrValueEntity::getAttrValue)));
        }, executor);
        //10.根据spuId查询spu下所有销售属性组合 和 skuId 映射关系 V
        CompletableFuture<Void> stringFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<String> mappingBySpuId = gmallPmsApi.queryMappingBySpuId(skuEntity.getSpuId());
            String mappingBySpuIdData = mappingBySpuId.getData();
            itemVo.setSkuJsons(mappingBySpuIdData);
        }, executor);
        //11.根据spuId查询spu的描述信息 V
        CompletableFuture<Void> spuDescFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<SpuDescEntity> spuDescEntityResponseVo = gmallPmsApi.querySpuDescById(skuEntity.getSpuId());
            SpuDescEntity spuDescEntity = spuDescEntityResponseVo.getData();
            String[] strings = StringUtils.split(spuDescEntity.getDecript(), ",");
            itemVo.setSpuImages(Arrays.asList(strings));
        }, executor);
        //12.根据cid、spuId、skuId查询分组及组下的规格参数和值
        CompletableFuture<Void> GroupFuture = skuFuture.thenAcceptAsync(skuEntity -> {
            ResponseVo<List<ItemGroupVo>> listResponseVo2 = gmallPmsApi.queryGroupsWitAttrsAndValuesByCidAndSkuIdAndSpuId(skuEntity.getCategoryId(), skuId, skuEntity.getSpuId());
            List<ItemGroupVo> itemGroupVos = listResponseVo2.getData();
            itemVo.setGroups(itemGroupVos);
        }, executor);
        //等待所有异步执行完毕
        CompletableFuture.allOf(skuFuture, skuDescFuture,
                spuDescFuture, spuFuture,
                saleFuture, saleAttrFuture,
                wareFuture, GroupFuture,
                stringFuture, skuAttrFuture,
                brandFuture, cateFuture).join();
        //异步生成静态页面
        asyncExecute(itemVo);
        return itemVo;
    }

    public void asyncExecute(ItemVo itemVo){
        executor.execute(()->{
            generateHtml(itemVo);
        });
    }

    public void generateHtml(ItemVo itemVo){
        //创建上下文对象
        try(PrintWriter printWriter = new PrintWriter("D:\\project-0325\\html\\" +itemVo.getSkuId()+".html")) {
            Context context = new Context();
            context.setVariable("itemVo",itemVo);
            this.templateEngine.process("item",context,printWriter);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
